#include <process.h>
#include <cstdlib>
#include <iostream>
#include "Socket/rwSocket.h"
#include "Tools/myLog.h"
#include "Tools/config.h"
#include "Tools/utility.h"
#include "Tools/message.h"
#include "Character/User.h"
#include "Room/room.h"
#include "login.h"
#include "main.h"
#include "global.h"

using namespace std;

map<string, User*> AllUser;

unsigned __stdcall Connection(void* a) {
	extern map<string, User*> AllUser;
	// Get user connection time.
	struct tm *newtime;
	time_t aclock;
	time(&aclock); /* Get time in seconds */
	
	rwSocket* s = (rwSocket*)a;
	cout << "Connect Address : " << s << endl;
	//new a User object
	User u = User("");
	u.longLastCMDTime = aclock;
	
	//Set user status in login process.
	u.UserProfile.iLoginStatus = 1;
	u.UserProfile.blNeedKickOut = false;
	u.UserProfile.Socket = s;
	login::loginProcess(&u);
	
	bool blForceLogout = false;
	while (1) {
		string strRecv = utility::trim(s->ReceiveLine());
		if (strRecv == "@@EXIT@@") break;
		time(&aclock); /* Get time in seconds */
		if ((aclock - u.longLastCMDTime) > 60)
		{
			s->SendLine(message::GetNormalMessage(1000));
			break;
		}
		else
		{
			if (strRecv == "") continue;
			if (strRecv == u.UserProfile.strUserInput)
			{
				u.UserProfile.iSameCommand++;
				if (u.UserProfile.iSameCommand > 100)
				{
					s->SendLine(message::GetNormalMessage(1002));
					break;
				}
			}
			else
			{
				u.UserProfile.iSameCommand = 0;
			}
			u.longLastCMDTime = aclock;
			u.UserProfile.strUserInput = strRecv;
			if (!u.UserProfile.isLogined)
			{
				login::loginProcess(&u);
			}
			else
			{
				u.CommandHandler(strRecv);
			}
		}
		if (u.UserProfile.blNeedKickOut)
		{
			s->SendLine("You got force kickout.");
			s->SendLine(message::GetNormalMessage(1000));
			break;
		}
		/*
		s->SendLine("Delay 3000");
		Sleep(3000);
		*/
	}
	AllUser.erase(u.UserData[ Const.userName ]);
	

	delete s;
	cout << "connection deleted." << endl;
	return 0;
}

int main(int argc, char *argv[])
{
    myLog m = myLog("main");
    m.writelog("Program main start.");
    m.writelog("Load Rooms.");
	room::init();
    config cf;
    bool blLoadConfigFlag = cf.LoadConfig();//Load system config settings.
    if (blLoadConfigFlag) 
    {
		/*
		const char COL_RESET[] = "\x1b[0m";
		const char RED[]     = "\x1b[31m";
		const char GREEN[]   = "\x1b[32m";
		const char YELLOW[]  = "\x1b[33m";
		const char BLUE[]    = "\x1b[34m";
		const char MAGENTA[] = "\x1b[35m";
		const char CYAN[]    = "\x1b[36m";
		
		cout << RED     << "Red looks good" << endl;
		cout << GREEN   << "Green looks good" << endl;
		cout << YELLOW  << "Yellow looks good" << endl;
		cout << BLUE    << "Blue looks good" << endl;
		cout << MAGENTA << "Magenta looks good" << endl;
		cout << CYAN    << "Cyan looks good" << COL_RESET << endl;
		cout << "This text should have the normal color" << endl;				
		// */

		//Load system successfully
		//display some system information.
	    m.displaylog("Version : " + cf.cfg.Version);
	    m.displaylog(message::GetNormalMessage(50001) + " " + cf.cfg.PortNumber);
	    m.displaylog(message::GetNormalMessage(50002) + " " + cf.cfg.MaxUsersNum);
	    
	    SocketServer in(utility::string2int(cf.cfg.PortNumber), utility::string2int(cf.cfg.MaxUsersNum));
		while (1) {
			rwSocket* s=in.Accept();
			unsigned ret;
			_beginthreadex(0,0,Connection,(void*) s,0,&ret);
		}
	    
		//cf.SetConfigVariable("BuatRate","5000");//Setting config variable
		//cf.SaveConfig();
	}
	else
	{
		m.displaylog(message::GetNormalMessage(60001));
	}
	
    m.writelog("Program main End.");

    system("PAUSE");
    return EXIT_SUCCESS;
}
